package com.markerhub.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.markerhub.common.ResponseCode;
import com.markerhub.common.ResponseJson;
import com.markerhub.common.shiro.MyLoginToken;
import com.markerhub.entity.Blog;
import com.markerhub.entity.User;
import com.markerhub.mapper.BlogMapper;
import com.markerhub.service.BlogService;
import com.markerhub.service.UserService;
import com.markerhub.service.impl.KaptchaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.jvm.hotspot.debugger.Page;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 关注公众号：MarkerHub
 * @since 2021-04-10
 */
@Api(value = "UserController",tags = "用户接口")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;
    @Autowired
    DefaultKaptcha defaultKaptcha;

    @Autowired
    KaptchaService kaptchaService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @ApiOperation(value = "修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "用户名",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "password",value = "密码",required = true,dataType = "String",paramType = "query"),
    })
    @PostMapping("/change_password")
    public Object change_password(String username, String password){
        try{
            boolean book=userService.changepassword(username,password);
            if(book)
                return ResponseJson.success("修改成功");
            else
                return ResponseJson.failure("密码不可与原密码相同");
        }catch (Exception e){
            return  ResponseJson.failure(e.getMessage());
        }
    }


    @ApiOperation(value = "用户登录",notes = "选择普通用户或者管理员登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "用户名",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "password",value = "密码",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "cToken",value = "验证码证书",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "code",value = "验证码",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "loginType",value = "用户类型（user/admin）",required = true,dataType = "String",paramType = "query"),

    })
    @PostMapping("/login")
    public Object login(String username, String password,String loginType,String cToken,String code){
        //检查验证码
        try{
            if(!stringRedisTemplate.opsForValue().get(cToken).toLowerCase().equals(code.toLowerCase())){
                return ResponseJson.failure(ResponseCode.USER_VERIFICATION_CODE_ERROR);
            }
        }catch (Exception e){
            return ResponseJson.failure(ResponseCode.USER_VERIFICATION_CODE_ERROR);
        }
        User user = userService.finduserByUserName(username);
        if(user == null){
            return ResponseJson.failure(ResponseCode.USER_NOT_EXIST);
        }else if(user.getDataStatus()==0){
            return ResponseJson.failure(ResponseCode.USER_ACCOUNT_FORBIDDEN);
        }
        MyLoginToken myLoginToken = new MyLoginToken(username, password, loginType);
        Subject subject = SecurityUtils.getSubject();
        try{
            //通过shiro的方法进行认证登录
            subject.login(myLoginToken);
            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put("sessionId", subject.getSession().getId());//登录成功返回sessionId
          //  return ResponseJson.success(returnMap);
            return ResponseJson.success(user);
        }catch (UnknownAccountException e1){
            return ResponseJson.failure(ResponseCode.USER_NOT_EXIST);
        }catch (IncorrectCredentialsException e2){
            return ResponseJson.failure(ResponseCode.USER_LOGIN_ERROR);
        }
    }

    @ApiOperation(value = "获取验证码",notes = "返回cToken,登录时携带，图片以base64方式转码")
    @GetMapping("/captcha")
    public Object captcha()  {

        try{
            // 生成文字验证码
            String text = defaultKaptcha.createText();
            // 生成图片验证码
            ByteArrayOutputStream outputStream = null;
            BufferedImage image = defaultKaptcha.createImage(text);

            outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "jpg", outputStream);

            // 对字节数组Base64编码
            String encode = Base64.getEncoder().encodeToString(outputStream.toByteArray());
            // 生成captcha的token
            Map<String, Object> map = kaptchaService.createToken(text);
            map.put("img",encode);
            map.put("code",text);
            return ResponseJson.success(map);
        }catch (Exception e){
            return  ResponseJson.failure(e.getMessage());
        }
    }

    @ApiOperation(value = "添加用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username",value = "用户名",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "password",value = "密码",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "nickname",value = "昵称",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "email",value = "邮箱",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "avatar",value = "头像链接",required = true,dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "type",value = "用户类型",required = true,dataType = "String",paramType = "query"),
    })
    @PostMapping("/add_user")
    public Object add_user(String username, String password,String nickname,String email,String avatar,String type){
        try{
            boolean book=userService.add_user(username,password,nickname,email,avatar,type);
            if(book)
                return ResponseJson.success("添加成功");
            else
                return ResponseJson.failure("该用户名以存在");
        }catch (Exception e){
            return  ResponseJson.failure(e.getMessage());
        }
    }
    /**
     * logout，为了在文档中显示有这么一个接口，实际不会走这个方法，会被shiro logoutFilter拦截
     * @return
     */
    @ApiOperation(value = "logout接口")
    @GetMapping("/logout")
    public Object logout(){
        return ResponseJson.success();
    }
    /**
     * logout成功，给前端返回数据用，前端无需可见这个接口
     * @return
     */
    @ApiOperation(value = "logout成功",hidden = true)
    @GetMapping("/logoutsuccess")
    public Object logoutsuccess(){
        //返回前台数据，提示logout成功
        return ResponseJson.success();
    }
}
